Order-agnostic Binary Search (easy)
We'll cover the following
Problem Statement #
Given a sorted array of numbers, find if a given number ākeyā is present in the array. Though we know that the array is sorted, we donāt know if itās sorted in ascending or descending order. You should assume that the array can have duplicates.
Write a function to return the index of the ākeyā if it is present in the array, otherwise return -1.
Example 1:
Input: [4, 6, 10], key = 10
Output: 2
Example 2:
Input: [1, 2, 3, 4, 5, 6, 7], key = 5
Output: 4
Example 3:
Input: [10, 6, 4], key = 10
Output: 0
Example 4:
Input: [10, 6, 4], key = 4
Output: 2
Try it yourself #
Try solving this question here:
Solution #
To make things simple, letās first solve this problem assuming that the input array is sorted in ascending order. Here are the set of steps for Binary Search:
- Letās assume
start
is pointing to the first index andend
is pointing to the last index of the input array (letās call itarr
). This means:
int start = 0;
int end = arr.length - 1;
- First, we will find the
middle
ofstart
andend
. An easy way to find the middle would be: . For Java and C++, this equation will work for most cases, but whenstart
orend
is large, this equation will give us the wrong result due to integer overflow. Imagine thatstart
is equal to the maximum range of an integer (e.g. for Java:int start = Integer.MAX_VALUE
). Now adding anything tostart
will result in an integer overflow. Since we need to add both the numbers first to evaluate our equation, an overflow might occur. The safest way to find the middle of two numbers without getting an overflow is as follows:
middle = start + (end-start)/2
The above discussion is not relevant for Python, as we donāt have the integer overflow problem in pure Python.
- Next, we will see if the ākeyā is equal to the number at index
middle
. If it is equal we returnmiddle
as the required index. - If ākeyā is not equal to number at index
middle
, we have to check two things:- If
key < arr[middle]
, then we can conclude that thekey
will be smaller than all the numbers after indexmiddle
as the array is sorted in the ascending order. Hence, we can reduce our search toend = mid - 1
. - If
key > arr[middle]
, then we can conclude that thekey
will be greater than all numbers before indexmiddle
as the array is sorted in the ascending order. Hence, we can reduce our search tostart = mid + 1
.
- If
- We will repeat steps 2-4 with new ranges of
start
toend
. If at any timestart
becomes greater thanend
, this means that we canāt find the ākeyā in the input array and we must return ā-1ā.
Here is the visual representation of Binary Search for the Example-2:
If the array is sorted in the descending order, we have to update the step 4 above as:
- If
key > arr[middle]
, then we can conclude that thekey
will be greater than all numbers after indexmiddle
as the array is sorted in the descending order. Hence, we can reduce our search toend = mid - 1
. - If
key < arr[middle]
, then we can conclude that thekey
will be smaller than all the numbers before indexmiddle
as the array is sorted in the descending order. Hence, we can reduce our search tostart = mid + 1
.
Finally, how can we figure out the sort order of the input array? We can compare the numbers pointed out by start
and end
index to find the sort order. If arr[start] < arr[end]
, it means that the numbers are sorted in ascending order otherwise they are sorted in the descending order.
Code #
Here is what our algorithm will look like: